/**
 * Tree control class. Tree control contains multiple items,
 * which can be any of control type, such as TreeItem, or any other.
 *
 * @author Andrey Anisimov <hercules@inbox.ru>
 */

import core.ui.Window;
import core.ui.TreeItem;
import core.util.Listeners;

class Tree extends Window {

	this.Tree = function(parent, x, y, width, height) {
		super(parent, x, y, width, height);
		this.items = [];
		this.listeners = new Listeners([
            'onItemSelected',
            'onItemStateChange'
        ]);
	}

	this.addTreeListener = function(listener) {
		this.listeners.add(listener);
	}

	this.removeTreeListener = function(listener) {
		this.listeners.remove(listener);
	}

	/**
	 * Adds new item to the tree.
	 * 
	 * @param item (Window) tree item control.
	 * @return Window
	 */
	this.addItem = function(item) {
		this.items.push(item);
		return item;
	}
	
	/**
	 * Gets the top-level tree item with specified index.
	 * 
	 * @param index (int) item index.
	 */
	this.getItem = function(i) {
		return this.items[i];
	}
	
	/**
	 * Gets top-levet item count.
	 *
	 * @return int
	 */
	this.getItemCount = function(i) {
		return this.items.length;
	}
	
	/**
	 * Removes top-level item with specified index.
	 * 
	 * @param index (int) item index.
	 */
	this.removeItem = function(i) {
		this.items[i].close();
		delete this.items[i];
		this.items.splice(i, 1);
	}
	
	/**
	 * Removes all top level tree items.
	 */
	this.removeItems = function() {
		while (this.items.length > 0) {
			var item = this.items.pop();
			item.close();
			delete item;
		}
		delete this.selectedItem;
	}

	/**
	 * Return item index. For removeItem(), for example.
	 */
	this.getItemIndexById = function(id) {
		for (var i=0; i < this.items.length; i++) {
			if (this.items[i].getId() == id) {
				return i;
			}
		}
		return false;
	}
	
	/**
	 * Closes tree item and deletes its content.
	 */
	this.close = function() {
		delete this.selectedItem;
		super.close();
	}

	/**
	 * @protected
	 */
	this.fireItemSelected = function() {
		this.listeners.call('onItemSelected', [this]);
	}

	/**
	 * @protected
	 * @param item
	 */
	this.fireItemStateChange = function(item) {
		this.listeners.call('onItemStateChange', [this, item]);
	}

	/**
	 * Select specified item.
	 * 
	 * @param item (Window) tree item control.
	 */
	this.selectItem = function(item) {
		if (this.selectedItem instanceof TreeItem) {
			this.selectedItem.setSelected(false);
		}
		item.setSelected(true);
		this.selectedItem = item;
		this.fireItemSelected();
	}
	
	this.onmousedown = function(event, item) {
		if ((item instanceof TreeItem) && !item.isSelected()) {
			this.selectItem(item);
			event.cancel();
			event.stop();
		}
	}
	
	this.ondblclick = function(event, item) {
		if ((item instanceof TreeItem) && !item.isLeaf()) {
			item.setState(!item.getState());
			this.fireItemStateChange(item);
			event.cancel();
			event.stop();
		}
	}
}